use super::index_entry::IndexEntry;
use crate::config::app_error::AppResult;
use crate::extension::index::index::index_entry_operator::IndexEntryOperator;
use crate::extension::index::index::indexer::DefaultIndexer;
use crate::extension::index::index::key_comparator;
use crate::extension::index::index::query::index_attribute::IndexAttribute;
use crate::extension::index::index::query::index_spec::PRIMARY_INDEX_NAME;
use crate::extension::index::index::query::query::query_factory::Query;
use crate::extension::index::page_request::Order;
use crate::extension::index::{index::indexer::Indexer, page_request::Sort};
use halo_model::{ExtensionGVK, ExtensionOperator, GVK};
use ordermap::OrderSet;
use std::cmp::Ordering;
use std::collections::HashMap;
use std::{cell::RefCell, hash::Hash, sync::Arc};

pub(crate) mod all;
pub(crate) mod and;
pub(crate) mod between;
pub(crate) mod equal;
pub(crate) mod greater_than;
pub(crate) mod in_query;
pub(crate) mod is_not_null;
pub(crate) mod is_null;
pub(crate) mod less_than;
pub(crate) mod not;
pub(crate) mod not_equal;
pub(crate) mod or;
pub(crate) mod query_factory;
pub(crate) mod string_contains;
pub(crate) mod string_ends_with;
pub(crate) mod string_starts_with;

pub trait BaseQuery {
    fn matches(&self, index_view: &QueryIndexView<DefaultIndexer>) -> AppResult<OrderSet<String>>;
}

pub struct QueryIndexView<I: Indexer> {
    indexer: Arc<RefCell<I>>,
}

impl<I: Indexer> QueryIndexView<I> {
    pub fn new<T: ExtensionGVK>(indexer: Arc<RefCell<I>>) -> AppResult<Self> {
        indexer.borrow().get_index_entry::<T>(PRIMARY_INDEX_NAME)?;
        Ok(QueryIndexView { indexer })
    }
    pub fn get_entry_operator<T: ExtensionGVK>(
        &self,
        field_name: &str,
    ) -> AppResult<IndexEntryOperator<I::Entry<T>>> {
        let result = self.get_index_entry::<T>(field_name)?;
        Ok(self.create_index_entry_operation(Arc::clone(&result)))
    }
    pub fn create_index_entry_operation<T: ExtensionGVK>(
        &self,
        entry: Arc<RefCell<I::Entry<T>>>,
    ) -> IndexEntryOperator<I::Entry<T>> {
        IndexEntryOperator::new(entry)
    }
    pub fn all_ids<T: ExtensionGVK>(&self) -> AppResult<OrderSet<String>> {
        let index_entry = self.get_index_entry::<T>(PRIMARY_INDEX_NAME)?;
        Ok(self
            .create_index_entry_operation(Arc::clone(&index_entry))
            .get_values())
    }
    pub fn find_ids_with_key_comparator<F, T: ExtensionGVK>(
        &self,
        field_name1: &str,
        field_name2: &str,
        key_comparator: F,
    ) -> AppResult<OrderSet<String>>
    where
        F: Fn(&str, &str) -> bool,
    {
        let mut key_map = HashMap::new();

        self.get_index_entry::<T>(field_name1)?
            .borrow()
            .entries()
            .for_each(|(key, value)| {
                if !key_map.contains_key(value) {
                    key_map.insert(value.clone(), vec![key.clone()]);
                }
            });
        let mut result = OrderSet::new();
        self.get_index_entry::<T>(field_name2)?
            .borrow()
            .entries()
            .for_each(|(key, value)| {
                let match_keys = key_map.get(value);
                if let Some(match_keys) = match_keys {
                    for match_key in match_keys {
                        if key_comparator(key, match_key) {
                            result.insert(value.clone());
                            // found one match, no need to continue
                            break;
                        }
                    }
                }
            });
        Ok(result)
    }

    pub fn comparator_from<T: ExtensionGVK>(
        &self,
        order: &Order,
    ) -> AppResult<impl Fn(&String, &String) -> Ordering> {
        let index_entry = self.get_index_entry::<T>(&order.property)?;
        let id_position_map = index_entry.borrow().get_id_position_map();
        let is_desc = order.direction.is_descending();
        let a = move |a: &String, b: &String| {
            let index_of_a = id_position_map.get(a);
            let index_of_b = id_position_map.get(b);

            match (index_of_a, index_of_b) {
                (None, None) => Ordering::Equal,
                (Some(x), None) => {
                    if is_desc {
                        Ordering::Greater
                    } else {
                        Ordering::Less
                    }
                }
                (None, Some(x)) => {
                    if is_desc {
                        Ordering::Less
                    } else {
                        Ordering::Greater
                    }
                }
                (Some(a_val), Some(b_val)) => {
                    if is_desc {
                        b_val.cmp(a_val)
                    } else {
                        a_val.cmp(b_val)
                    }
                }
            }
        };
        Ok(a)
    }

    pub fn find_ids<T: ExtensionGVK>(
        &self,
        field_name: &str,
        field_value: &str,
    ) -> AppResult<OrderSet<String>> {
        let operator = self.get_entry_operator::<T>(field_name)?;
        Ok(operator.find(field_value))
    }

    pub fn get_ids_for_field<T: ExtensionGVK>(
        &self,
        field_name: &str,
    ) -> AppResult<OrderSet<String>> {
        let operator = self.get_entry_operator::<T>(field_name)?;
        Ok(operator.get_values())
    }

    fn get_all_ids<T: ExtensionGVK>(&self) -> AppResult<OrderSet<String>> {
        self.all_ids::<T>()
    }

    pub fn find_matching_ids_with_equal_values<T: ExtensionGVK>(
        &self,
        field_name1: &str,
        field_name2: &str,
    ) -> AppResult<OrderSet<String>> {
        Ok(
            self.find_ids_with_key_comparator::<_,T>(field_name1, field_name2, |a, b| {
                key_comparator::compare(a, b) == Ordering::Equal
            })?,
        )
    }

    pub fn find_matching_ids_with_greater_values<T: ExtensionGVK>(
        &self,
        field_name1: &str,
        field_name2: &str,
        or_equal: bool,
    ) -> AppResult<OrderSet<String>> {
        Ok(
            self.find_ids_with_key_comparator::<_,T>(field_name1, field_name2, |a, b| {
                let order = key_comparator::compare(a, b);
                if or_equal {
                    order == Ordering::Equal || order == Ordering::Less
                } else {
                    order == Ordering::Less
                }
            })?,
        )
    }

    pub fn find_ids_greater_than<T: ExtensionGVK>(
        &self,
        field_name: &str,
        field_value: &String,
        or_equal: bool,
    ) -> AppResult<OrderSet<String>> {
        let operator = self.get_entry_operator::<T>(field_name)?;
        Ok(operator.greater_then(field_value, or_equal))
    }

    pub fn find_matching_ids_with_smaller_values<T: ExtensionGVK>(
        &self,
        field_name1: &str,
        field_name2: &str,
        or_equal: bool,
    ) -> AppResult<OrderSet<String>> {
        Ok(
            self.find_ids_with_key_comparator::<_,T>(field_name1, field_name2, |a, b| {
                let order = key_comparator::compare(a, b);
                if or_equal {
                    order == Ordering::Equal || order == Ordering::Greater
                } else {
                    order == Ordering::Greater
                }
            })?,
        )
    }

    pub fn find_ids_less_than<T: ExtensionGVK>(
        &self,
        field_name: &str,
        field_value: &String,
        or_equal: bool,
    ) -> AppResult<OrderSet<String>> {
        let operator = self.get_entry_operator::<T>(field_name)?;
        Ok(operator.less_than(field_value, or_equal))
    }

    pub fn between<T: ExtensionGVK>(
        &self,
        field_name: &str,
        lower_value: &String,
        lower_inclusive: bool,
        upper_value: &String,
        upper_inclusive: bool,
    ) -> AppResult<OrderSet<String>> {
        let operator = self.get_entry_operator::<T>(field_name)?;
        Ok(operator.range(lower_value, upper_value, lower_inclusive, upper_inclusive))
    }

    pub fn sort_by<T: ExtensionGVK>(
        &self,
        ids: OrderSet<String>,
        sort: &Sort,
    ) -> AppResult<Vec<String>> {
        let mut comparators = vec![];
        for order in &sort.orders {
            comparators.push(self.comparator_from::<T>(order)?);
        }

        // 组合多个比较器
        let combined_comparator = |a: &String, b: &String| {
            comparators
                .iter()
                .fold(Ordering::Equal, |order, comparator| match order {
                    Ordering::Equal => comparator(a, b),
                    x => order,
                })
        };
        let mut sort_ids = ids.iter().cloned().collect::<Vec<String>>();
        sort_ids.sort_by(combined_comparator);
        Ok(sort_ids)
    }

    pub fn get_index_entry<T: ExtensionGVK>(
        &self,
        field_name: &str,
    ) -> AppResult<Arc<RefCell<I::Entry<T>>>> {
        self.indexer.borrow().get_index_entry::<T>(field_name)
    }

    fn acquire_read_lock(&self) {
        todo!()
    }

    fn release_read_lock(&self) {
        todo!()
    }
}

#[cfg(test)]
mod query_index_view_impl_tests {
    use super::*;
    use crate::extension::index::page_request::Direction;
    use crate::tests::index_view_data_set::{
        create_comment_index_view, create_employee_index_view,
        create_post_index_view_with_null_cell, pile_for_indexer, FakeExtension, MockIndexEntry,
        MockIndexer,
    };

    // 测试获取所有字段的 I
    #[test]
    fn get_all_ids_for_field_test() {
        let index_view = create_post_index_view_with_null_cell();
        let result_set = index_view.get_ids_for_field::<FakeExtension>("title").unwrap();
        assert_eq!(
            result_set,
            OrderSet::from([
                "100".to_string(),
                "101".to_string(),
                "102".to_string(),
                "103".to_string(),
                "104".to_string(),
                "105".to_string(),
                "106".to_string(),
                "107".to_string(),
                "108".to_string()
            ])
        );

        let result_set = index_view.get_ids_for_field::<FakeExtension>("publishTime").unwrap();
        assert_eq!(
            result_set,
            OrderSet::from([
                "100".to_string(),
                "101".to_string(),
                "105".to_string(),
                "106".to_string(),
                "107".to_string()
            ])
        );
    }

    // 测试查找具有相等值的 I
    #[test]
    fn find_ids_for_value_equal_test() {
        let index_view = create_employee_index_view();
        let result_set = index_view
            .find_matching_ids_with_equal_values::<FakeExtension>("managerId", PRIMARY_INDEX_NAME)
            .unwrap();
        assert_eq!(
            result_set,
            OrderSet::from(["102".to_string(), "103".to_string()])
        );
    }

    // 测试查找大于某个值的 I
    #[test]
    fn find_ids_for_field_value_greater_than_test() {
        let index_view = create_employee_index_view();
        let result_set = index_view
            .find_matching_ids_with_greater_values::<FakeExtension>(PRIMARY_INDEX_NAME, "managerId", false)
            .unwrap();
        assert_eq!(
            result_set,
            OrderSet::from(["104".to_string(), "105".to_string()])
        );

        let index_view = create_employee_index_view();
        let result_set = index_view
            .find_matching_ids_with_greater_values::<FakeExtension>(PRIMARY_INDEX_NAME, "managerId", true)
            .unwrap();
        assert_eq!(
            result_set,
            OrderSet::from([
                "102".to_string(),
                "103".to_string(),
                "104".to_string(),
                "105".to_string()
            ])
        );
    }

    #[test]
    fn find_ids_for_field_value_greater_than_test2() {
        let index_view = create_employee_index_view();
        let result_set = index_view
            .find_matching_ids_with_greater_values::<FakeExtension>("managerId", PRIMARY_INDEX_NAME, false)
            .unwrap();
        assert_eq!(
            result_set,
            OrderSet::from(["100".to_string(), "101".to_string()])
        );

        let index_view = create_employee_index_view();
        let result_set = index_view
            .find_matching_ids_with_greater_values::<FakeExtension>("managerId", PRIMARY_INDEX_NAME, true)
            .unwrap();
        assert_eq!(
            result_set,
            OrderSet::from([
                "100".to_string(),
                "101".to_string(),
                "102".to_string(),
                "103".to_string()
            ])
        );
    }

    #[test]
    fn find_ids_for_field_value_less_than_test() {
        let index_view = create_employee_index_view();
        let result_set = index_view
            .find_matching_ids_with_smaller_values::<FakeExtension>(PRIMARY_INDEX_NAME, "managerId", false)
            .unwrap();
        assert_eq!(
            result_set,
            OrderSet::from(["100".to_string(), "101".to_string()])
        );

        let index_view = create_employee_index_view();
        let result_set = index_view
            .find_matching_ids_with_smaller_values::<FakeExtension>(PRIMARY_INDEX_NAME, "managerId", true)
            .unwrap();
        assert_eq!(
            result_set,
            OrderSet::from([
                "100".to_string(),
                "101".to_string(),
                "102".to_string(),
                "103".to_string()
            ])
        );
    }

    #[test]
    fn find_ids_for_field_value_less_than_test2() {
        let index_view = create_employee_index_view();
        let result_set = index_view
            .find_matching_ids_with_smaller_values::<FakeExtension>("managerId", PRIMARY_INDEX_NAME, false)
            .unwrap();
        assert_eq!(
            result_set,
            OrderSet::from(["104".to_string(), "105".to_string()])
        );

        let index_view = create_employee_index_view();
        let result_set = index_view
            .find_matching_ids_with_smaller_values::<FakeExtension>("managerId", PRIMARY_INDEX_NAME, true)
            .unwrap();
        assert_eq!(
            result_set,
            OrderSet::from([
                "102".to_string(),
                "103".to_string(),
                "104".to_string(),
                "105".to_string()
            ])
        );
    }

    // 测试排序方法，未排序的情况
    #[test]
    fn test_sort_by_unsorted() {
        let index_entry =
            MockIndexEntry::<FakeExtension>::mock(Vec::new(), HashMap::new(), OrderSet::new());
        let mut map = HashMap::new();
        map.insert(
            PRIMARY_INDEX_NAME.to_string(),
            Arc::new(RefCell::new(index_entry)),
        );
        let indexer = MockIndexer::mock_with(map);
        let index_view = QueryIndexView::new::<FakeExtension>(Arc::new(RefCell::new(indexer))).unwrap();
        let sort = Sort::unsorted();
        let mut result_set = OrderSet::new();
        result_set.insert("Item1".to_string());
        result_set.insert("Item2".to_string());
        let sorted_list = index_view.sort_by::<FakeExtension>(result_set, &sort).unwrap();
        assert_eq!(sorted_list, vec!["Item1".to_string(), "Item2".to_string()]);
    }

    // 测试排序方法，按单个字段升序排序
    #[test]
    fn test_sort_by_sorted_ascending() {
        // 准备测试数据和环境

        let mut index_entry: HashMap<String, Arc<RefCell<MockIndexEntry<FakeExtension>>>> =
            HashMap::new();
        pile_for_indexer(
            &mut index_entry,
            "field1".to_string(),
            vec![
                ("key2".to_string(), "Item2".to_string()),
                ("key1".to_string(), "Item1".to_string()),
            ],
        );
        pile_for_indexer(
            &mut index_entry,
            PRIMARY_INDEX_NAME.to_string(),
            vec![
                ("Item1".to_string(), "Item1".to_string()),
                ("Item2".to_string(), "Item2".to_string()),
            ],
        );

        let index_view =
            QueryIndexView::new::<FakeExtension>(Arc::new(RefCell::new(MockIndexer::mock_with(index_entry))))
                .unwrap();
        let sort = Sort::by(vec![("field1".to_string())], Direction::Asc);
        let all_ids = index_view.get_all_ids::<FakeExtension>().unwrap();
        let sorted_list = index_view.sort_by::<FakeExtension>(all_ids, &sort).unwrap();

        // 验证排序结果是否与预期一致
        assert_eq!(sorted_list, vec!["Item1".to_string(), "Item2".to_string()]);
    }

    #[test]
    fn test_sort_by_sorted_descending() {
        // 准备测试数据和环境

        let mut index_entry: HashMap<String, Arc<RefCell<MockIndexEntry<FakeExtension>>>> =
            HashMap::new();
        pile_for_indexer(
            &mut index_entry,
            "field1".to_string(),
            vec![
                ("key1".to_string(), "Item1".to_string()),
                ("key2".to_string(), "Item2".to_string()),
            ],
        );
        pile_for_indexer(
            &mut index_entry,
            PRIMARY_INDEX_NAME.to_string(),
            vec![
                ("Item1".to_string(), "Item1".to_string()),
                ("Item2".to_string(), "Item2".to_string()),
            ],
        );

        let index_view =
            QueryIndexView::new::<FakeExtension>(Arc::new(RefCell::new(MockIndexer::mock_with(index_entry))))
                .unwrap();
        let sort = Sort::by(vec![("field1".to_string())], Direction::Desc);
        let mut result_set = OrderSet::new();
        result_set.insert("Item1".to_string());
        result_set.insert("Item2".to_string());
        let sorted_list = index_view.sort_by::<FakeExtension>(result_set, &sort).unwrap();
        // 验证排序结果是否与预期一致
        assert_eq!(sorted_list, vec!["Item2".to_string(), "Item1".to_string()]);
    }

    #[test]
    fn test_sort_by_multiple_fields() {
        // 准备测试数据和环境
        let mut index_entry: HashMap<String, Arc<RefCell<MockIndexEntry<FakeExtension>>>> =
            HashMap::new();
        pile_for_indexer(
            &mut index_entry,
            "field1".to_string(),
            vec![
                ("k3".to_string(), "Item3".to_string()),
                ("k2".to_string(), "Item2".to_string()),
            ],
        );
        pile_for_indexer(
            &mut index_entry,
            "field2".to_string(),
            vec![
                ("k1".to_string(), "Item1".to_string()),
                ("k3".to_string(), "Item3".to_string()),
            ],
        );
        pile_for_indexer(
            &mut index_entry,
            PRIMARY_INDEX_NAME.to_string(),
            vec![
                ("Item1".to_string(), "Item1".to_string()),
                ("Item2".to_string(), "Item2".to_string()),
                ("Item3".to_string(), "Item3".to_string()),
            ],
        );

        let index_view =
            QueryIndexView::new::<FakeExtension>(Arc::new(RefCell::new(MockIndexer::mock_with(index_entry))))
                .unwrap();
        let sort = Sort::by_any(vec![
            ("field1".to_string(), Direction::Asc),
            ("field2".to_string(), Direction::Desc),
        ]);

        let mut all_ids = OrderSet::new();
        all_ids.insert("Item1".to_string());
        all_ids.insert("Item2".to_string());
        all_ids.insert("Item3".to_string());
        let sorted_list = index_view.sort_by::<FakeExtension>(all_ids, &sort).unwrap();
        // 验证排序结果是否与预期一致
        assert_eq!(
            sorted_list,
            vec![
                "Item2".to_string(),
                "Item3".to_string(),
                "Item1".to_string()
            ]
        );
    }

    #[test]
    fn test_sort_by_multiple_fields2() {
        // 准备测试数据和环境
        let mut index_entry: HashMap<String, Arc<RefCell<MockIndexEntry<FakeExtension>>>> =
            HashMap::new();
        pile_for_indexer(&mut index_entry, PRIMARY_INDEX_NAME.to_string(), Vec::new());
        pile_for_indexer(
            &mut index_entry,
            "field1".to_string(),
            vec![
                ("John".to_string(), "John".to_string()),
                ("Bob".to_string(), "Bob".to_string()),
                ("Alice".to_string(), "Alice".to_string()),
            ],
        );
        pile_for_indexer(
            &mut index_entry,
            "field2".to_string(),
            vec![
                ("David".to_string(), "David".to_string()),
                ("Eva".to_string(), "Eva".to_string()),
                ("Frank".to_string(), "Frank".to_string()),
            ],
        );
        pile_for_indexer(
            &mut index_entry,
            "field3".to_string(),
            vec![
                ("George".to_string(), "George".to_string()),
                ("Helen".to_string(), "Helen".to_string()),
                ("Ivy".to_string(), "Ivy".to_string()),
            ],
        );

        /*
         * ```
         * Row Key | field1 | field2 | field3
         * -------|-------|-------|-------
         * John   | John  |       |
         * Bob    | Bob   |       |
         * Alice  | Alice |       |
         * David  |       | David |
         * Eva    |       | Eva   |
         * Frank  |       | Frank |
         * George |       |       | George
         * Helen  |       |       | Helen
         * Ivy    |       |       | Ivy
         * ```
         */
        let index_view =
            QueryIndexView::new::<FakeExtension>(Arc::new(RefCell::new(MockIndexer::mock_with(index_entry))))
                .unwrap();
        let orders = vec![
            Order::desc("field1".to_string()),
            Order::asc("field2".to_string()),
            Order::asc("field3".to_string()),
        ];
        let sort = Sort::new(orders);
        let result_set = [
            "Bob".to_string(),
            "John".to_string(),
            "Eva".to_string(),
            "Alice".to_string(),
            "Ivy".to_string(),
            "David".to_string(),
            "Frank".to_string(),
            "Helen".to_string(),
            "George".to_string(),
        ]
        .into();
        let sorted_list = index_view.sort_by::<FakeExtension>(result_set, &sort).unwrap();
        // 验证排序结果是否与预期一致
        assert_eq!(
            sorted_list,
            vec![
                "David".to_string(),
                "Eva".to_string(),
                "Frank".to_string(),
                "George".to_string(),
                "Helen".to_string(),
                "Ivy".to_string(),
                "John".to_string(),
                "Bob".to_string(),
                "Alice".to_string()
            ]
        );
    }

    /**
     * <p>Result for the following data.</p>
     * <pre>
     *  | id | firstName | lastName | email | hireDate | salary | managerId | departmentId |
     * |----|-----------|----------|-------|----------|--------|-----------|--------------|
     * | 100| Pat       | Fay      | p     | 17       | 2600   | 101       | 50           |
     * | 101| Lee       | Day      | l     | 17       | 2400   | 102       | 40           |
     * | 103| Mary      | Day      | p     | 17       | 2000   | 103       | 50           |
     * | 104| John      | Fay      | j     | 17       | 1800   | 103       | 50           |
     * | 105| Gon       | Fay      | p     | 18       | 1900   | 101       | 40           |
     * | 102| William   | Jay      | w     | 19       | 2200   | 102       | 50           |
     * </pre>
     */
    #[test]
    fn sort_by_multiple_fields_with_first_same() {
        let index_view = create_employee_index_view();
        let ids = index_view.get_all_ids::<FakeExtension>().unwrap();
        let result = index_view
            .sort_by::<FakeExtension>(
                ids,
                &Sort::new(vec![
                    Order::asc("hireDate".to_string()),
                    Order::asc("lastName".to_string()),
                ]),
            )
            .unwrap();
        assert_eq!(
            result,
            vec![
                "101".to_string(),
                "103".to_string(),
                "100".to_string(),
                "104".to_string(),
                "105".to_string(),
                "102".to_string()
            ]
        )
    }

    /**
     * <p>Result for the following data.</p>
     * <pre>
     * | id  | title  | published | publishTime         | owner |
     * |-----|--------|-----------|---------------------|-------|
     * | 100 | title1 | true      | 2024-01-01T00:00:00 | jack  |
     * | 101 | title2 | true      | 2024-01-02T00:00:00 | rose  |
     * | 105 | title6 | true      | 2024-01-05 00:00:00 | tom   |
     * | 107 | title8 | true      | 2024-01-05 12:00:00 | jerry |
     * | 106 | title7 | true      | 2024-01-05 13:00:00 | jerry |
     * | 108 | title9 | false     | null                | jerry |
     * | 104 | title5 | false     | null                | john  |
     * | 103 | title4 | false     | null                | peter |
     * | 102 | title3 | false     | null                | smith |
     * </pre>
     */
    #[test]
    fn sort_by_multiple_fields_for_post_data_set() {
        let index_view = create_post_index_view_with_null_cell();
        let ids = index_view.get_all_ids::<FakeExtension>().unwrap();
        let result = index_view
            .sort_by::<FakeExtension>(
                ids,
                &Sort::new(vec![
                    Order::asc("publishTime".to_string()),
                    Order::desc("title".to_string()),
                ]),
            )
            .unwrap();
        assert_eq!(
            result,
            vec![
                "100".to_string(),
                "101".to_string(),
                "105".to_string(),
                "107".to_string(),
                "106".to_string(),
                "108".to_string(),
                "104".to_string(),
                "103".to_string(),
                "102".to_string()
            ]
        )
    }

    #[test]
    fn sort_by_multiple_fields_for_comment_data_set() {
        let index_view = create_comment_index_view();
        let ids = index_view.get_all_ids::<FakeExtension>().unwrap();
        let result = index_view
            .sort_by::<FakeExtension>(
                ids,
                &Sort::new(vec![
                    Order::desc("spec.top".to_string()),
                    Order::asc("spec.priority".to_string()),
                    Order::desc("spec.creationTime".to_string()),
                    Order::asc("metadata.name".to_string()),
                ]),
            )
            .unwrap();
        assert_eq!(
            result,
            vec![
                "1".to_string(),
                "2".to_string(),
                "4".to_string(),
                "3".to_string(),
                "5".to_string(),
                "6".to_string(),
                "9".to_string(),
                "10".to_string(),
                "8".to_string(),
                "7".to_string(),
                "11".to_string(),
                "12".to_string(),
                "14".to_string(),
                "13".to_string()
            ]
        )
    }
}

pub(crate) fn get_field_names_used_in_query(query: &Query) -> Vec<String> {
    let mut field_names = Vec::new();
    match query {
        Query::All(x) => {
            let is_field_ref = x.is_field_ref;
            if is_field_ref {
                field_names.push(x.value.clone());
            }
            field_names.push(x.field_name.clone());
        }
        Query::And(x) => {
            let child_query = &x.child_queries;
            for x in child_query {
                field_names.extend(get_field_names_used_in_query(x))
            }
        }
        Query::Or(x) => {
            let child_query = &x.child_queries;
            for x in child_query {
                field_names.extend(get_field_names_used_in_query(x))
            }
        }
        Query::Between(x) => {
            field_names.push(x.field_name.clone());
        }
        Query::GreaterThan(x) => {
            let is_field_ref = x.is_field_ref;
            if is_field_ref {
                field_names.push(x.value.clone());
            }
            field_names.push(x.field_name.clone());
        }
        Query::In(x) => {
            field_names.push(x.field_name.clone());
        }
        Query::IsNull(x) => {
            let is_field_ref = x.is_field_ref;
            if is_field_ref {
                field_names.push(x.value.clone());
            }
            field_names.push(x.field_name.clone());
        }
        Query::IsNotNull(x) => {
            let is_field_ref = x.is_field_ref;
            if is_field_ref {
                field_names.push(x.value.clone());
            }
            field_names.push(x.field_name.clone());
        }
        Query::LessThan(x) => {
            let is_field_ref = x.is_field_ref;
            if is_field_ref {
                field_names.push(x.value.clone());
            }
            field_names.push(x.field_name.clone());
        }
        Query::Equal(x) => {
            let is_field_ref = x.is_field_ref;
            if is_field_ref {
                field_names.push(x.value.clone());
            }
            field_names.push(x.field_name.clone());
        }
        Query::Not(x) => field_names.extend(get_field_names_used_in_query(&x.negated_query)),
        Query::NotEqual(x) => {
            let is_field_ref = x.is_field_ref;
            if is_field_ref {
                field_names.push(x.value.clone());
            }
            field_names.push(x.field_name.clone());
        }
        Query::StringStartsWith(x) => {
            let is_field_ref = x.is_field_ref;
            if is_field_ref {
                field_names.push(x.value.clone());
            }
            field_names.push(x.field_name.clone());
        }
        Query::StringEndsWith(x) => {
            let is_field_ref = x.is_field_ref;
            if is_field_ref {
                field_names.push(x.value.clone());
            }
            field_names.push(x.field_name.clone());
        }
        Query::StringContains(x) => {
            let is_field_ref = x.is_field_ref;
            if is_field_ref {
                field_names.push(x.value.clone());
            }
            field_names.push(x.field_name.clone());
        }
    }
    field_names
}
